package org.agilelang.mvc;

/*
 AgileLang - A fourth generation language(http://www.agilelang.org).

 Copyright (C) 2013 Roderick Cusirramos (roderick20@hotmail.com)

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;
import javax.imageio.ImageIO;
import org.agilelang.object.Application;
import org.agilelang.object.Controller;
import org.agilelang.object.Menu;
import org.agilelang.object.Model;
import org.agilelang.object.WebClient;
import org.agilelang.object.WebServices;
import org.agilelang.object.attributes.Attribute;
import org.agilelang.object.attributes.MenuItem;
import org.agilelang.object.attributes.Reference;
import org.agilelang.object.attributes.View;
import org.agilelang.object.attributes.ViewForm;
import org.agilelang.object.attributes.ViewReport;
import org.agilelang.util.Inflector;

public class Generator {

    protected String template = "";

    public String getTemplate() {
        return template;
    }

    public void setTemplate(String template) {
        this.template = template;
    }
    protected String template2 = "";

    public String getTemplate2() {
        return template2;
    }

    public void setTemplate2(String template) {
        this.template2 = template;
    }
    protected String path = "";
    protected String appName = "";
    protected String TAB = "\t";
    protected String BR = "\r\n";
    protected List<Controller> controllers;
    protected List<Menu> menus;
    protected List<Model> models;
    protected List<WebClient> webclients;
    protected List<WebServices> webservices;
    protected Application app;

    public String setPluralize(String aLine) {
        return Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(aLine));
    }

    public String setSingularize(String aLine) {
        return Inflector.getInstance().capitalize(Inflector.getInstance().singularize(aLine));
    }

    public Controller getControllerByName(String name) {
        int t = controllers.size();
        for (int x = 0; x < t; x++) {
            Controller co = controllers.get(x);
            if (co.name.equals(name)) {
                return co;
            }
        }
        return null;
    }

    public Reference isKey(String namemodel, String atrr) {
        Model model = this.getModelByName(namemodel);
        int tr = model.references.size();
        for (int j = 0; j < tr; j++) {
            Reference reference = model.references.get(j);
            if(reference.foreign_key.equals(atrr)){
                return reference;
            }
        }
        return null;
    }

    public String getTyeView(String controller, String function) {
        int t = controllers.size();
        for (int x = 0; x < t; x++) {
            Controller co = controllers.get(x);
            if (co.name.equals(controller)) {
                for (int y = 0; y < co.views.size(); y++) {
                    View v = co.views.get(y);
                    if (v.name.equals(function)) {
                        return "View";
                    }
                }
                for (int y = 0; y < co.forms.size(); y++) {
                    ViewForm v = co.forms.get(y);
                    if (v.name.equals(function)) {
                        return "ViewForm";
                    }
                }
                for (int y = 0; y < co.reports.size(); y++) {
                    ViewReport v = co.reports.get(y);
                    if (v.name.equals(function)) {
                        return "ViewReport";
                    }
                }

                //return co;
            }
        }
        return "";
    }

    public Model getModelByName(String name) {
        int t = models.size();
        for (int x = 0; x < t; x++) {
            Model mo = models.get(x);
            if (mo.name.equals(name)) {
                return mo;
            }
        }
        return null;
    }

    public WebServices getWebServicesByName(String name) {
        int t = webservices.size();
        for (int x = 0; x < t; x++) {
            WebServices mo = webservices.get(x);
            if (mo.name.equals(name)) {
                return mo;
            }
        }
        return null;
    }

    public String[] getModelParams(String name) {
        int t = models.size();
        for (int x = 0; x < t; x++) {
            Model mo = models.get(x);
            if (mo.name.equals(name)) {
                List<Attribute> attrs = mo.attributes;
                int ta = attrs.size();
                String params[] = new String[ta];
                for (int xx = 0; xx < ta; xx++) {
                    Attribute a = attrs.get(xx);
                    params[xx] = a.name;
                }
                return params;
            }
        }
        return null;
    }

    public Menu getMenuByName(String name) {
        int t = menus.size();
        for (int x = 0; x < t; x++) {
            Menu me = menus.get(x);
            if (me.name.equals(name)) {
                return me;
            }
        }
        return null;
    }

    protected static String readFileAsString(Reader reader) {
        StringBuffer fileData = new StringBuffer(100000);
        char[] buf = new char[1024];
        int numRead = 0;
        try {
            while ((numRead = reader.read(buf)) != -1) {
                String readData = String.valueOf(buf, 0, numRead);
                fileData.append(readData);
                buf = new char[1024];
            }
            reader.close();
        } catch (IOException ex) {
            System.out.println(ex.toString());
        }
        return fileData.toString();
    }

    protected void createfile(String Name, String path, String Contenido) {
        Writer output = null;
        System.out.println(path + File.separator + Name);
        File file = new File(path + File.separator + Name);
        try {
            output = new BufferedWriter(new FileWriter(file));
            output.write(Contenido);
            output.close();
        } catch (IOException ex) {
            System.out.println(ex.toString());
        }
    }

    protected void createDirectory(String path) {
        File folder = new File(path);
        if (!folder.exists()) {
            folder.mkdirs();
            System.out.println("createDirectory : " + folder.getAbsolutePath());
        }
    }

    protected String readStream(String path, String tpl) {
        Reader reader = null;
        try {
            InputStream is = this.getClass().getResourceAsStream(path + tpl);
            if (is != null) {
                try {
                    reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        String file = readFileAsString(reader);
        return file;
    }

    protected String readStream(String path) {
        Reader reader = null;
        try {
            InputStream is = this.getClass().getResourceAsStream(path);
            if (is != null) {
                try {
                    reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                } catch (Exception e) {
                    System.out.println(e.toString() + "111111");
                }
            }
        } catch (Exception e) {
            System.out.println(e.toString() + "222222");
        }
        String file = readFileAsString(reader);
        return file;
    }

    protected String readStreamTpl(String tpl) {
        return readStream("/org/agilelang/generator/" + this.template2 + "/" + this.template + "/", tpl);
    }

    protected String readStreamFiles(String tpl2, String tpl) {
        return readStream("/org/agilelang/generator/" + tpl2 + "/" + this.template + "/files/", tpl);
    }

    protected void createImageIcon(String tpl, String pathint, String path) {
        BufferedImage image = null;
        try {
            System.out.println("/org/agilelang/generator/" + tpl + "/" + this.template + "/files/" + pathint);
            java.net.URL url = getClass().getResource("/org/agilelang/generator/" + tpl + "/" + this.template + "/files/" + pathint);
            image = ImageIO.read(url);
            if(path.endsWith(".png")){
                ImageIO.write(image, "png", new File(path));
            }
            if(path.endsWith(".gif")){
                ImageIO.write(image, "GIF", new File(path));
            }
        } catch (IOException e) {
            System.out.println(e.toString());
        }
    }

    protected String readfile(String file) {
        String strfile = "";
        try {
            FileInputStream fstream = new FileInputStream(file);
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String strLine;
            while ((strLine = br.readLine()) != null) {
                strfile = strfile + strLine;
            }
            in.close();
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
        }
        return strfile;
    }

    public void fileRelocateFile(String tpl, String filename, String path) {
        System.out.println(path);
        System.out.println("/org/agilelang/generator/" + tpl + "/" + this.template + "/files/" + filename);
        String contenido = this.readStream("/org/agilelang/generator/" + tpl + "/" + this.template + "/files/" + filename);
        Writer output = null;

        File file = new File(path);
        try {
            output = new BufferedWriter(new FileWriter(file));
            output.write(contenido);
            output.close();
        } catch (IOException ex) {
            System.out.println(ex.toString() + "xxxx");
        }
    }

    public void fileRelocate(String tpl, String filename, String path) {
        System.out.println(path);
        String contenido = this.readStream("/org/agilelang/generator/" + tpl + "/" + this.template + "/files/" + filename);
        Writer output = null;
        System.out.println(path);
        File file = new File(path);
        try {
            output = new BufferedWriter(new FileWriter(file));
            output.write(contenido);
            output.close();
        } catch (IOException ex) {
            System.out.println(ex.toString());
        }
    }

    public void fileRelocateByte(String filename, String path) {
        System.out.println(path);
        String contenido = this.readStream(filename);
        Writer output = null;
        System.out.println(path);
        File file = new File(path);
        try {
            output = new BufferedWriter(new FileWriter(file));
            output.write(contenido);
            output.close();
        } catch (IOException ex) {
            System.out.println(ex.toString());
        }
    }

    public String name(String name) {
        char[] stringArray = name.toCharArray();
        stringArray[0] = Character.toUpperCase(stringArray[0]);
        return new String(stringArray);

    }

    public String searchMenu(String controller, String view) {
        String menu = "";
        int t = menus.size();
        for (int i = 0; i < t; i++) {
            int tt = menus.get(i).menuitems.size();
            for (int ii = 0; ii < tt; ii++) {
                MenuItem menuitem = menus.get(i).menuitems.get(ii);
                if (menuitem.controller.equals(controller) && menuitem.action.equals(view)) {
                    menu = menus.get(i).name.toLowerCase();
                    break;
                }
            }
        }
        return menu;
    }

    public String searchMenuItem(String controller, String view) {
        String menu = "";
        int t = menus.size();
        for (int i = 0; i < t; i++) {
            int tt = menus.get(i).menuitems.size();
            for (int ii = 0; ii < tt; ii++) {
                MenuItem menuitem = menus.get(i).menuitems.get(ii);
                if (menuitem.controller.equals(controller) && menuitem.action.equals(view)) {
                    menu = menuitem.name.toLowerCase();
                    break;
                }
            }
        }
        return menu;
    }
}
